package mols;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.ContentConnection;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.ImageItem;
import javax.microedition.location.Coordinates;
import org.json.me.JSONObject;

/**
 * Classe che interfaccia la MIDlet con i servizi di Google Local Search e
 * Google Static Maps.
 */
public class GoogleRequestStub {

    // l'URL da utilizzare per la connessione a Google Static Map
    private static String staticMapBaseUrl =
            "http://maps.google.com/maps/api/staticmap?" +
            "key=ABQIAAAA5m8c4gkSKJUTN_3TOiFEaxT2yXp_ZAY8_ufC3CFXhHIE1Nvwkx"+
            "Ti8z_Ux5aCQjobNgz_vln_gVVYwA&";

    // l'URL da utilizzare per la connessione a Google Local Search
    private static String localSearchBaseUrl =
            "http://ajax.googleapis.com/ajax/services/search/local?"+
            "v=1.0&rsz=large&";

    // costruisce l'URL che rappresenta la richiesta di mappa statica
    // a partire dai parametri richiesti.
    private static String getGoogleMapRequest(Coordinates[] points,
            int zoomLevel, int imgWidth, int imgHeight,
            String[] labels, String[] colors){

        StringBuffer googleRequest = new StringBuffer(staticMapBaseUrl.length());
        googleRequest.append(staticMapBaseUrl);
        
        if (zoomLevel != -1){
            googleRequest.append("&zoom=");
            googleRequest.append(zoomLevel);
        }

        googleRequest.append("&size=");
        googleRequest.append(imgWidth).append("x").append(imgHeight);

        googleRequest.append("&maptype=roadmap&mobile=true");

        StringBuffer markersBuffer = new StringBuffer();
        
        for (int i=0; i<points.length; i++){
            markersBuffer.append("&markers=color:");
            markersBuffer.append(colors[i]);
            markersBuffer.append("|label:");
            markersBuffer.append(labels[i]).append("|");
            markersBuffer.append(points[i].getLatitude());
            markersBuffer.append(",");
            markersBuffer.append(points[i].getLongitude());
        }
        
        googleRequest.append(markersBuffer.toString());

        googleRequest.append("&sensor=true");
        return googleRequest.toString();
    }

    /**
     * Ottiene una mappa statica da google nella quale sono visualizzati
     * determinati punti.
     *
     * @param points punti da visualizzare.
     * @param zoomLevel livello di zoom della mappa. Se -1 lo zoom non viene
     *  preso in considerazione nella richiesta a google static map.
     * @param imgWidth larghezza in pixel della mappa richiesta.
     * @param imgHeight altezza in pixel della mappa richiesta.
     *
     * @return un oggetto ImageItem che incapsula la mappa richiesta, oppure
     *  null se l'operazione non &egrave; andata a buon fine.
     */
    public static ImageItem getStaticMap(Coordinates[] points, int zoomLevel,
            int imgWidth, int imgHeight, String[] labels, String[] colors){

        String googleRequestUrl = getGoogleMapRequest
            (points, zoomLevel, imgWidth, imgHeight, labels, colors);

        ContentConnection hc = null;
        DataInputStream in = null;
        ImageItem result = null;

        try{
            hc = (ContentConnection)Connector.open(googleRequestUrl);
                    // VISUALIZZAZIONE MAPPA
            int length = (int)hc.getLength();
            byte[] data = null;
            if (length != -1) {
                data = new byte[length];
                in = new DataInputStream(hc.openInputStream());
                in.readFully(data);
            } else
            {
                int chunkSize = 512;
                int index = 0;
                int readLength = 0;
                in = new DataInputStream(hc.openInputStream());
                data = new byte[chunkSize];
                do {
                    if (data.length < index + chunkSize) {
                        byte[] newData = new byte[index + chunkSize];
                        System.arraycopy(data, 0, newData, 0, data.length);
                        data = newData;
                    }
                    readLength = in.read(data, index, chunkSize);
                    index += readLength;
                 } while (readLength == chunkSize);

                length = index;
            }

            Image image = Image.createImage(data, 0, length);
            result = new ImageItem(null, image, ImageItem.LAYOUT_CENTER, null);

        } catch(IOException ioe){} finally {
           try {
               if (in != null) in.close();
               if (hc != null) hc.close();
          } catch (IOException ioe) {}
        }
        return result;
    }

    /**
     * Ottiene una lista di punti di interesse dal servizio di Google Local
     * Search.
     *
     * @param centre il punto geografico che rappresenta il centro della
     *      ricerca, incapsulato in un oggetto <code>Coordinates</code>.
     * @param query oggetto <code>String</code> contenente i punti di interesse
     *      da cercare (e.g. &quot;cinema|ristoranti&quot;)
     *
     * @return un oggetto <code>JSONObject</code> che incapsula la risposta
     *      proveniente da Google Local Search.
     */
    public static JSONObject getPOIsFromGoogle
                (Coordinates centre, String query){

        StringBuffer googleRequest = new StringBuffer(localSearchBaseUrl.length());
        googleRequest.append(localSearchBaseUrl);
        googleRequest.append("q=").append(query);
        googleRequest.append("&sll=");
        googleRequest.append(centre.getLatitude()).append(",");
        googleRequest.append(centre.getLongitude());

        ContentConnection hc = null;
        InputStream is = null;
        JSONObject result = null;
        try{
            hc = (ContentConnection)Connector.open(googleRequest.toString());
            is = hc.openDataInputStream();
            StringBuffer googleResponse = new StringBuffer();
            int ch;
            while((ch = is.read()) != -1){
                googleResponse.append((char)ch);
            }
            result = new JSONObject(googleResponse.toString());
          
        } catch(Exception e){
        } finally {
            try {
                if (is != null) is.close();
                if (hc != null) hc.close();
            } catch (IOException ioe) {}
        }
        
        return result;
    }
}
